
#include "Self_Define_Functions.h"


/*
*
*
*
*
*
*
*
*
*
*
*
*
*/


// create new object of class for different functions
Benchmarks* generateFuncObj(int funcID)
{
	Benchmarks *fp;
	// run each of specified function in "configure.ini"
	if (funcID==1){
		fp = new F1();
	}else if (funcID==2){
		fp = new F2();
	}else if (funcID==3){
		fp = new F3();
	}else if (funcID==4){
		fp = new F4();
	}else if (funcID==5){
		fp = new F5();
	}else if (funcID==6){
		fp = new F6();
	}else if (funcID==7){
		fp = new F7();
	}else if (funcID==8){
		fp = new F8();
	}else if (funcID==9){
		fp = new F9();
	}else if (funcID==10){
		fp = new F10();
	}else if (funcID==11){
		fp = new F11();
	}else if (funcID==12){
		fp = new F12();
	}else if (funcID==13){
		fp = new F13();
	}else if (funcID==14){
		fp = new F14();
	}else if (funcID==15){
		fp = new F15();
	}else{
		cerr<<"Fail to locate Specified Function Index"<<endl;
		exit(-1);
	}
	return fp;
}

bool Compare_NewType( NewType data1, NewType data2 )
{
    return data1.data < data2.data;
}


void Fitness( double &results, double *particle,  int &FV, Benchmarks* fp )
{
    results =  fp->compute( particle );
    FV++;
}


//Fitness Computation
void Fitness_Computation( double *results, double **population, int &gbest, int num, int dim, int &FV, Benchmarks* fp )
{// num is the population size and dim is the size of dimensions
    int i;
    double best = results[0] = fp->compute( population[0] );
    gbest = 0;
    for( i = 1; i < num; ++i )
    {
        results[i] = fp->compute( population[i]);

        if( results[i] < best )
        {
            best = results[i];
            gbest = i;
        }
    }

    FV += num;
}

void Update_Particle( double *particle, double *speed, double *exemplar1, double *exemplar2, double *lb, double *ub, int dim, double phi, double sign )
{
    int i;

    double r1,r2,r3;

    boost::mt19937 generator(time(0)*rand());

    boost::uniform_real<> uniform_real_generator2( 0, 1 );
    boost::variate_generator< boost::mt19937&, boost::uniform_real<> > random_0_1( generator, uniform_real_generator2 );


    for( i = 0; i < dim; ++i )
    {
        r1 = random_0_1();
        r2 = random_0_1();
        r3 = random_0_1();

        speed[i] = r1*speed[i] + r2*( exemplar1[i] - particle[i] ) + sign*phi*r3*( exemplar2[i]-particle[i] );

        particle[i] = particle[i] + speed[i];

        if( particle[i] < lb[i] )
        {
            particle[i] = lb[i];
        }

        if( particle[i] > ub[i] )
        {
            particle[i] = ub[i];
        }
    }
}

void Rank( int *ranking, double *population_results, NewType *temp, int population_size )
{

    int i;

    for( i = 0; i < population_size; ++i )
    {
        temp[i].data = population_results[i];
        temp[i].id = i;
    }

    sort( temp, temp+population_size, Compare_NewType );

    for( i = 0; i < population_size; ++i )
    {
        ranking[temp[i].id] = i;
    }

}

void Sort_Population( int *sorted_index, double *population_results, NewType *temp, int population_size )
{

    int i;

    for( i = 0; i < population_size; ++i )
    {
        temp[i].data = population_results[i];
        temp[i].id = i;
    }

    sort( temp, temp+population_size, Compare_NewType );

    for( i = 0; i < population_size; ++i )
    {
        sorted_index[i] = temp[i].id;
    }

}












